/* Promise链式阶乘 */
function fn1() {
  function multiply(a, b, callback) {
    setTimeout(() => {
      const ret = a * b;
      callback(ret);
    }, 2000);
  }
  // multiply(2,3,ret=>console.log("ret=",ret))

  /* 但凡耗时任务的结果，要么回调，要么Promise */
  function mulPromise(a, b) {
    return new Promise((resolve, reject) => {
      multiply(2, 3, (ret) => resolve(ret));
    });
  }

  //   mulPromise(2, 3)
  //     // .then((ret) => ret * 4)
  //     .then((ret) => mulPromise(ret, 4))
  //     .then((ret) => mulPromise(ret, 4))
  //     .then((ret) => console.log("最终结果", ret));

  /* await */
  ~(async function awaitDemo() {
    try {
      let ret = await mulPromise(2, 3);
      ret = await mulPromise(ret, 4);
      ret = await mulPromise(ret, 5);
      console.log("最终结果", ret);
    } catch (err) {
      console.log("err=", err);
    }
  })();
}
// fn1();

/* 防抖 */
const inputHander = (e) => {
  console.log(e.target.value);
};
function debounce(fn, delay = 1000) {
  let timer = null;
  return function dfn(...args) {
    /* 新的fn调用时 若发现上次还有没来得及回调的fn 直接取消 */
    timer && clearTimeout(timer);

    // 1秒后回调本次fn
    timer = setTimeout(() => {
      fn.apply(null, args);
      timer = null;
    }, delay);
  };
}
ip.addEventListener("input", debounce(inputHander, 1000));

/* 节流 */
const clickHandler = (e) => {
  console.log("hello");
};
function throttle(fn, delay = 1000) {
  let forbidTimer = null;

  return function (...args) {
    if (!forbidTimer) {
      fn.apply(null, args);

      // 1秒内不允许再有人来调用fn
      forbidTimer = setTimeout(() => {
        forbidTimer = null;
      }, delay);
    }
  };
}
btn.addEventListener("click", throttle(clickHandler, 1000));

/* 
JSON Web Token
作用：登录鉴权 单点登录（多点开花）
细节：
token构成：头部（算法等配置信息）+载荷（用户的详细信息）+签名（头+载荷+秘钥三合一综合计算而成）
token签发：用户在A服务器登录，成功以后A服务器做三合一的计算得到一个token，作为登录结果返还客户端
token携带：客户端通过请求头【authorization:Bearer xxx】携带
token校验：B服务器与A服务器持有相同的JWT秘钥，可以对用户携带的token进行校验
核心库API：
const token = jsonwebtoken.generate(payload,secret) 
const payloadOrFalse = jsonwebtoken.verify(token,secret)
注意事项：保管好秘钥
*/